package my.shadowsocks.server;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 负责访问被代理的客户端想访问的地址
 * @author fengbo
 * @date 2018/10/6
 */
public class InternetDataHandler extends ChannelInboundHandlerAdapter {

    private static final Logger log = LoggerFactory.getLogger(InternetDataHandler.class);

    private ClientProxyHandler clientProxyHandler;
    private ChannelHandlerContext ctx;
    private ByteBuf cacheBuf;

    InternetDataHandler(ClientProxyHandler clientProxyHandler, ByteBuf cacheBuf) {
        this.clientProxyHandler = clientProxyHandler;
        this.cacheBuf = cacheBuf;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf buf = (ByteBuf) msg;
        int readBytes = buf.readableBytes();
        int writeBytes = buf.writableBytes();
        int capacity = buf.capacity();
        System.out.println("============read " + readBytes
                + "=========write" + writeBytes
                + "=========capacity" + capacity);
        // TODO 下载文件时因为网速不匹配会出现OutOfDirectMemoryError
        clientProxyHandler.sendMsg(msg);
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        this.ctx = ctx;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ctx.writeAndFlush(cacheBuf);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        log.info("InternetDataHandler channelInactive close");
        channelClose();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("InternetDataHandler throw error", cause);
        channelClose();
    }

    void sendMsg(Object msg) {
        ctx.writeAndFlush(msg);
    }

    private void channelClose() {
        ctx.close();
        if (cacheBuf != null) {
            cacheBuf.clear();
            cacheBuf = null;
        }
        clientProxyHandler.channelClose();
    }
}
